package com.gzdh.dishrecognition.util;

import android.util.Log;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.SecretKeySpec;

import static com.jiebao.util.CardReaderUtils.byteArray2HexString;
import static com.jiebao.util.CardReaderUtils.hexToByteArr;
import com.jiebao.nfc.uartnfc.CardReaderDevice;

public class TripleDESUtil {

    /**
     * 3DES ECB 模式加密（无填充）
     * @param key  双倍长密钥 (16字节)
     * @param data 待加密数据 (8字节)
     * @return 加密结果 (8字节)
     */
    public static byte[] encrypt3DES_ECB(byte[] key, byte[] data) throws Exception {
        // 检查密钥长度（必须为16字节）
        if (key == null || key.length != 16) {
            throw new IllegalArgumentException("Key must be 16 bytes for double-length 3DES");
        }

        // 将16字节密钥转换为24字节（K1 + K2 + K1）
        byte[] fullKey = new byte[24];
        System.arraycopy(key, 0, fullKey, 0, 16); // 复制前16字节
        System.arraycopy(key, 0, fullKey, 16, 8); // 将K1复制到最后8字节

        // 创建DESede密钥规范
        DESedeKeySpec keySpec = new DESedeKeySpec(fullKey);
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
        SecretKey secretKey = keyFactory.generateSecret(keySpec);

        // 创建并初始化加密器（ECB模式，无填充）
        Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        return cipher.doFinal(data);
    }

    /**
     * 复旦微电子CPU卡密钥验证流程
     * @param cardRandom 卡片返回的随机数 (8字节)
     * @param masterKey  主密钥 (16字节)
     * @return 加密后的结果 (8字节)
     */
    public static byte[] fmcosEncrypt(byte[] cardRandom, byte[] masterKey) throws Exception {
        // 使用3DES ECB模式加密卡片随机数
        return encrypt3DES_ECB(masterKey, cardRandom);
    }

    public static void main(String[] args) throws Exception {
        // 示例：复旦微电子CPU卡密钥验证
        byte[] masterKey = hexStringToByteArray("11111111111111112222222222222222");
        byte[] cardRandom = hexStringToByteArray("0123456789ABCDEF");

        byte[] encrypted = fmcosEncrypt(cardRandom, masterKey);

        System.out.println("加密结果: " + byteArrayToHex(encrypted));
    }

    // 辅助方法：16进制字符串转字节数组
    private static byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                    + Character.digit(s.charAt(i+1), 16));
        }
        return data;
    }

    // 辅助方法：字节数组转16进制字符串
    private static String byteArrayToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02X", b));
        }
        return sb.toString();
    }

    public static boolean cpuCardTest() throws Exception {
        boolean res = false;
        //复位CPU卡
        byte[] resetCard = CardReaderDevice.getInstance().resetCpuCard();
        if(resetCard != null) {
            String envStr[];
            //获取随机数
            envStr = CardReaderDevice.getInstance().CardCpuSendCosCmd(hexToByteArr("0084000008"));
            if(envStr[0].equals("9000"))
            {
                //随机数3DES加密。密钥：3D485A3BEF0103058888010208340102
                String desStr = encrypt3DES(envStr[1],"3D485A3BEF01030588880102083401023D485A3BEF010305");  //3DES加密中，对于16字节的密钥，K3=K1
                Log.e("TAG", "desStr " + desStr);
                //发送外部认证命令
                String cmdVerify = "0082000008" + desStr;
                envStr = CardReaderDevice.getInstance().CardCpuSendCosCmd(hexToByteArr(cmdVerify));
                Log.e("TAG", "envStr[0] " + envStr[0]);
                if(envStr[0].equals("9000"))
                    res = true;
            }
        }
        return res;
    }

    private static String encryptDES(String encryptString, String encryptKey) throws Exception {

        SecretKeySpec key = new SecretKeySpec(hexToByteArr(encryptKey), "DES");
        Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] encryptedData = cipher.doFinal(hexToByteArr(encryptString));
        return byteArray2HexString(encryptedData);
    }

    public static String encrypt3DES(String encryptString, String encryptKey) throws Exception {
        String string = encryptKey + encryptKey.substring(0, 16);
        DESedeKeySpec keySpec = new DESedeKeySpec(hexToByteArr(string));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
        SecretKey key = keyFactory.generateSecret(keySpec);
        Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] encryptedData = cipher.doFinal(hexToByteArr(encryptString));
        return byteArray2HexString(encryptedData);
    }
}